"""
文档加载模块

统一的高级文档加载接口，整合文件扫描、类型识别和文档读取功能。

重构后的模块结构：
- file_types.py: 文件类型支持和管理
- scanner.py: 文档扫描和发现
- readers.py: 文档读取策略
- document_loader.py: 统一加载接口
"""

from typing import List, Optional, Dict, Any
from llama_index.core.schema import Document

from ..config import config
from .scanner import DocumentScanner
from .readers import default_reader, EnhancedDocumentReader


class DocumentLoader:
    """
    高级文档加载器

    职责：
    1. 统一的文档加载接口
    2. 自动文件发现和类型识别
    3. 智能文档读取策略
    4. 加载进度监控和统计
    5. 错误处理和恢复机制

    特性：
    - 支持多种文档格式
    - 可配置的扫描策略
    - 增量加载支持
    - 详细的加载统计
    - 灵活的读取策略切换
    """

    def __init__(
        self,
        data_dir: Optional[str] = None,
        reader: Optional[EnhancedDocumentReader] = None,
        scanner: Optional[DocumentScanner] = None
    ):
        """
        初始化文档加载器

        Args:
            data_dir: 数据目录路径，默认使用配置中的路径
            reader: 文档读取器实例，默认使用增强读取器
            scanner: 文档扫描器实例，默认创建新实例
        """
        self.data_dir = data_dir or config.data_dir
        self.reader = reader or default_reader
        self.scanner = scanner or DocumentScanner(self.data_dir)

        # 加载配置
        self._include_patterns = None  # 可以从配置文件读取
        self._exclude_patterns = ['.git', '.svn', '__pycache__', '.DS_Store']
        self._max_scan_depth = None
        self._enable_statistics = True

    def load_documents(
        self,
        recursive: bool = True,
        show_progress: bool = False,
        file_patterns: Optional[List[str]] = None,
        max_retries: int = 3
    ) -> List[Document]:
        """
        加载文档

        Args:
            recursive: 是否递归扫描子目录
            show_progress: 是否显示加载进度
            file_patterns: 文件名模式过滤器
            max_retries: 加载失败时的重试次数

        Returns:
            List[Document]: 加载的文档列表
        """
        print(f"正在从 {self.data_dir} 加载文档...")

        # 1. 扫描文件
        files = self.scanner.scan_directory(
            recursive=recursive,
            include_patterns=file_patterns or self._include_patterns,
            exclude_patterns=self._exclude_patterns,
            max_depth=self._max_scan_depth
        )

        if not files:
            print("未找到任何支持的文档文件")
            return []

        print(f"发现 {len(files)} 个支持的文档文件")

        # 2. 显示扫描统计
        if self._enable_statistics:
            scan_stats = self.scanner.get_scan_statistics(files)
            print(f"文档总大小: {scan_stats['total_size_mb']} MB")
            print("文件类型分布:")
            for file_type, count in scan_stats['file_types'].items():
                print(f"  - {file_type}: {count} 个")

        # 3. 加载文档
        file_paths = [file.path for file in files]
        documents = self.reader.load_documents(
            file_paths,
            show_progress=show_progress,
            max_retries=max_retries
        )

        # 4. 显示加载统计
        if self._enable_statistics:
            load_stats = self.reader.get_load_statistics()
            print(f"文档加载完成:")
            print(f"  - 成功: {load_stats['successful_loads']} 个")
            print(f"  - 失败: {load_stats['failed_loads']} 个")
            print(f"  - 成功率: {load_stats['success_rate']:.1f}%")

            if load_stats['failed_files']:
                print(f"  - 失败文件: {', '.join(load_stats['failed_files'][:5])}")
                if len(load_stats['failed_files']) > 5:
                    print(f"    ... 还有 {len(load_stats['failed_files']) - 5} 个")

        return documents

    def get_supported_files(self) -> List[str]:
        """
        获取支持的文件列表

        Returns:
            List[str]: 支持的文件路径列表
        """
        files = self.scanner.scan_directory(
            recursive=True,
            include_patterns=self._include_patterns,
            exclude_patterns=self._exclude_patterns
        )
        return [file.path for file in files]

    def get_file_info(self, file_path: str) -> Dict[str, Any]:
        """
        获取文件详细信息

        Args:
            file_path: 文件路径

        Returns:
            Dict[str, Any]: 文件信息
        """
        try:
            file_info = self.scanner.file_type_registry.get_file_info(file_path)
            return {
                "path": file_info.path,
                "name": file_info.name,
                "extension": file_info.extension,
                "file_type": file_info.file_type.value,
                "size": file_info.size,
                "size_mb": round(file_info.size / (1024 * 1024), 2),
                "modified_time": file_info.modified_time,
                "is_supported": file_info.is_supported
            }
        except Exception as e:
            return {
                "path": file_path,
                "error": str(e),
                "is_supported": False
            }

    def validate_directory(self) -> bool:
        """
        验证数据目录

        Returns:
            bool: 目录是否有效
        """
        try:
            self.scanner.validate_directory()
            return True
        except (FileNotFoundError, NotADirectoryError) as e:
            print(f"目录验证失败: {e}")
            return False

    def get_file_stats(self) -> Dict[str, Any]:
        """
        获取数据目录的文件统计信息

        Returns:
            Dict[str, Any]: 包含文件统计信息的字典
        """
        try:
            # 扫描文件
            files = self.scanner.scan_directory()

            # 统计信息
            total_files = len(files)
            supported_files = sum(1 for f in files if f.is_supported)
            total_size = sum(f.size for f in files if f.is_supported)
            supported_size = sum(f.size for f in files if f.is_supported)

            # 按文件类型统计
            type_stats = {}
            for file_info in files:
                if file_info.is_supported:
                    file_type = file_info.file_type.value
                    if file_type not in type_stats:
                        type_stats[file_type] = {'count': 0, 'size': 0}
                    type_stats[file_type]['count'] += 1
                    type_stats[file_type]['size'] += file_info.size

            return {
                'total_files': total_files,
                'supported_files': supported_files,
                'unsupported_files': total_files - supported_files,
                'total_size': total_size,
                'supported_size': supported_size,
                'total_size_mb': round(total_size / (1024 * 1024), 2),
                'supported_size_mb': round(supported_size / (1024 * 1024), 2),
                'type_stats': type_stats,
                'scan_time': files[0].modified_time if files else 0
            }
        except Exception as e:
            return {
                'total_files': 0,
                'supported_files': 0,
                'unsupported_files': 0,
                'total_size': 0,
                'supported_size': 0,
                'total_size_mb': 0,
                'supported_size_mb': 0,
                'type_stats': {},
                'error': str(e)
            }

    def get_scan_report(self) -> str:
        """
        获取扫描报告

        Returns:
            str: 格式化的扫描报告
        """
        files = self.get_supported_files()
        file_infos = []
        for file_path in files:
            try:
                file_info = self.scanner.file_type_registry.get_file_info(file_path)
                file_infos.append(file_info)
            except Exception:
                continue

        return self.scanner.generate_scan_report(file_infos)

    def set_scan_patterns(
        self,
        include_patterns: Optional[List[str]] = None,
        exclude_patterns: Optional[List[str]] = None
    ) -> None:
        """
        设置扫描模式

        Args:
            include_patterns: 包含的文件模式
            exclude_patterns: 排除的文件模式
        """
        self._include_patterns = include_patterns
        self._exclude_patterns = exclude_patterns or self._exclude_patterns

    def set_max_scan_depth(self, max_depth: Optional[int]) -> None:
        """
        设置最大扫描深度

        Args:
            max_depth: 最大扫描深度，None表示无限制
        """
        self._max_scan_depth = max_depth

    def set_reader(self, reader: EnhancedDocumentReader) -> None:
        """
        设置文档读取器

        Args:
            reader: 文档读取器实例
        """
        self.reader = reader

    def enable_statistics(self, enabled: bool = True) -> None:
        """
        启用/禁用统计功能

        Args:
            enabled: 是否启用统计
        """
        self._enable_statistics = enabled

    def get_statistics(self) -> Dict[str, Any]:
        """
        获取完整的统计信息

        Returns:
            Dict[str, Any]: 统计信息
        """
        files = self.get_supported_files()
        file_infos = []
        for file_path in files:
            try:
                file_info = self.scanner.file_type_registry.get_file_info(file_path)
                file_infos.append(file_info)
            except Exception:
                continue

        scan_stats = self.scanner.get_scan_statistics(file_infos)
        load_stats = self.reader.get_load_statistics()

        return {
            "scan_statistics": scan_stats,
            "load_statistics": load_stats,
            "data_directory": self.data_dir,
            "total_files_found": len(files),
            "reader_type": type(self.reader).__name__
        }

    def reset_statistics(self) -> None:
        """重置所有统计信息"""
        self.reader.reset_statistics()

    def __str__(self) -> str:
        """返回加载器信息的字符串表示"""
        return f"""
=== 文档加载器 ===
数据目录: {self.data_dir}
扫描模式: {'递归' if self._max_scan_depth is None else f'深度{self._max_scan_depth}'}
统计功能: {'启用' if self._enable_statistics else '禁用'}
读取器类型: {type(self.reader).__name__}

当前状态:
- 目录有效: {self.validate_directory()}
- 支持文件数: {len(self.get_supported_files())}
        """.strip()


# 全局文档加载器实例
document_loader = DocumentLoader()